package com.treasure.mall.biz.service.core.live.impl;

import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.condition.LiveRoomFanCondition;
import com.treasure.mall.biz.dto.live.LiveRoomFanSaveDTO;
import com.treasure.mall.biz.entity.live.LiveRoomFanPO;
import com.treasure.mall.biz.entity.live.LiveRoomFanPO_;
import com.treasure.mall.biz.entity.live.LiveRoomPO_;
import com.treasure.mall.biz.entity.user.UserPO_;
import com.treasure.mall.biz.repository.live.LiveRoomFanRepository;
import com.treasure.mall.biz.service.core.live.LiveRoomFanService;
import com.treasure.mall.biz.service.core.live.LiveRoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * @author allan
 * @version 1.0.0
 * @date 2020/6/13
 */
@Service
public class LiveRoomFanServiceImpl extends AbstractSearchableCrudService<LiveRoomFanPO, Long> implements LiveRoomFanService {
    private LiveRoomFanRepository liveRoomFanRepository;
    @Autowired
    private LiveRoomService liveRoomService;

    @Autowired
    protected LiveRoomFanServiceImpl(LiveRoomFanRepository repository) {
        super(repository);
        this.liveRoomFanRepository = repository;
    }

    @Override
    protected SpecificationAndSort<LiveRoomFanPO> specificationAndSort(BaseSearchDTO searchDTO) {
        LiveRoomFanCondition condition = (LiveRoomFanCondition) searchDTO;

        Specification<LiveRoomFanPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (condition.getRoomId() > 0) {
                predicates.add(cb.equal(root.get(LiveRoomFanPO_.room).get(LiveRoomPO_.id), condition.getRoomId()));
            }

            if (condition.getUserId() != null && condition.getUserId() > 0) {
                predicates.add(cb.equal(root.get(LiveRoomFanPO_.user).get(UserPO_.userId), condition.getUserId()));
            }

            if (!StringUtils.isEmpty(condition.getUserKey())) {
                predicates.add(cb.or(
                        cb.like(root.get(LiveRoomFanPO_.user).get(UserPO_.nickName), likeAll(condition.getUserKey())),
                        cb.like(root.get(LiveRoomFanPO_.user).get(UserPO_.mobile), likeAll(condition.getUserKey()))
                ));
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    @Transactional
    public LiveRoomFanPO save(BaseSaveDTO saveDTO) {
        LiveRoomFanSaveDTO liveRoomFanSaveDTO = (LiveRoomFanSaveDTO) saveDTO;
        LiveRoomFanPO liveRoomFanPO = findByRoomAndUser(liveRoomFanSaveDTO.getRoomId(), liveRoomFanSaveDTO.getUserPO().getUserId());
        ;
        if (liveRoomFanPO != null) {
            return liveRoomFanPO;
        }
        liveRoomFanPO = new LiveRoomFanPO();
        liveRoomFanPO.setUser(liveRoomFanSaveDTO.getUserPO());
        liveRoomFanPO.setRoom(liveRoomService.findById(liveRoomFanSaveDTO.getRoomId()));
        return repository.save(liveRoomFanPO);
    }

    @Override
    @Transactional
    public void delete(Long roomId, Long userId) {
        liveRoomFanRepository.deleteByRoomIdAndUser_UserId(roomId, userId);
    }

    @Override
    public LiveRoomFanPO findByRoomAndUser(Long roomId, Long userId) {
        return liveRoomFanRepository.findByRoomIdAndUser_UserId(roomId, userId);
    }

    /**
     * 判断是否
     *
     * @param roomId
     * @param userId
     * @return
     */
    @Override
    public boolean countByRoomIdAndUserId(Long roomId, Long userId) {
        return liveRoomFanRepository.countByRoomIdAndUserId(roomId, userId) > 0;
    }

}
